package com.ruoyi.operation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.operation.domain.TOperationdaily;
import com.ruoyi.operation.domain.vo.DateVo;
import com.ruoyi.operation.mapper.TOperationdailyMapper;
import com.ruoyi.system.api.RemoteTBsCalendarService;
import com.ruoyi.system.api.domain.TBsCalendar;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import com.ruoyi.operation.domain.bo.TOperationdailyResultBo;
import com.ruoyi.operation.domain.vo.TOperationdailyResultVo;
import com.ruoyi.operation.domain.TOperationdailyResult;
import com.ruoyi.operation.mapper.TOperationdailyResultMapper;
import com.ruoyi.operation.service.ITOperationdailyResultService;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 运营部门日志记录结果Service业务层处理
 *
 * @author ruoyi
 * @date 2025-10-10
 */
@RequiredArgsConstructor
@Service
public class TOperationdailyResultServiceImpl implements ITOperationdailyResultService {

    private final TOperationdailyResultMapper baseMapper;

    private final TOperationdailyMapper tOperationdailyMapper;

    @DubboReference
    private RemoteTBsCalendarService tBsCalendarService;
    /**
     * 查询运营部门日志记录结果
     */
    @Override
    public TOperationdailyResultVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询运营部门日志记录结果列表
     */
    @Override
    public TableDataInfo<TOperationdailyResultVo> queryPageList(TOperationdailyResultBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TOperationdailyResult> lqw = buildQueryWrapper(bo);
        Page<TOperationdailyResultVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询运营部门日志记录结果列表
     */
    @Override
    public List<TOperationdailyResultVo> queryList(TOperationdailyResultBo bo) {
        LambdaQueryWrapper<TOperationdailyResult> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TOperationdailyResult> buildQueryWrapper(TOperationdailyResultBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TOperationdailyResult> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getExcutedate() != null, TOperationdailyResult::getExcutedate, bo.getExcutedate());
        lqw.eq(StringUtils.isNotBlank(bo.getDailyid()), TOperationdailyResult::getDailyid, bo.getDailyid());
        lqw.eq(StringUtils.isNotBlank(bo.getResult()), TOperationdailyResult::getResult, bo.getResult());
        lqw.eq(StringUtils.isNotBlank(bo.getMemo()), TOperationdailyResult::getMemo, bo.getMemo());
        return lqw;
    }

    /**
     * 新增运营部门日志记录结果
     */
    @Override
    public Boolean insertByBo(TOperationdailyResultBo bo) {
        TOperationdailyResult add = BeanUtil.toBean(bo, TOperationdailyResult.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改运营部门日志记录结果
     */
    @Override
    public Boolean updateByBo(TOperationdailyResultBo bo) {
        TOperationdailyResult update = BeanUtil.toBean(bo, TOperationdailyResult.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TOperationdailyResult entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除运营部门日志记录结果
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean generate(TOperationdailyResultBo bo) {
        /**
         * 找到模板对应的项。
         */
        /**
         * 找到所有的模板项。根据模板的period开头进行分组分类生成
         */
        QueryWrapper<TOperationdaily> qw = new QueryWrapper<>();
        qw.lambda().eq(TOperationdaily::getFlag,"1")
            .eq(TOperationdaily::getTemplatetype,bo.getTemplatetype())
            .isNull(TOperationdaily::getSpecificdate);
        List<TOperationdaily> list = tOperationdailyMapper.selectList(qw);

        List<TOperationdaily> realSaveList = new ArrayList<>();
        Map<String, List<TOperationdaily>> collect = list.stream().collect(Collectors.groupingBy(x -> x.getPeriod().substring(0, 1)));
        //今日日期字符串
//        String todayStr = DateUtil.format(DateUtil.date(), "yyyyMMdd");
        String todayStr = DateUtil.format(bo.getSpecificdate(), "yyyyMMdd");
        //按照D每日生成
        List<TOperationdaily> DList = collect.get("D");
        if(CollUtil.isNotEmpty(DList)){
            realSaveList.addAll(DList);
        }
        //按照T进行工作日生成
        List<TOperationdaily> TList = collect.get("T");
        if(CollUtil.isNotEmpty(TList)){
            //判断今天是否工作日
            TBsCalendar today = tBsCalendarService.selectTBsCalendarByNatureday(todayStr);
            if(today.getDealflag().equals("0")){
                realSaveList.addAll(TList);
            }
        }

        //按照W进行生成
        List<TOperationdaily> WList = collect.get("W");
        if(CollUtil.isNotEmpty(WList)){
            List<TOperationdaily> addList = WList.stream().filter(x -> {
                //如果带负号-则用7-对应的数字
                if(x.getPeriod().contains("-")){
                    DateVo dayInWeek = tOperationdailyMapper.getDayInWeek(todayStr,"desc");
                    //拿到对应的数字对7取余数
                    int day = Integer.parseInt(x.getPeriod().split("-")[1])%7;
                    //根据今天的字符串获取今天是这周的第几个工作日
                    if(Objects.nonNull(dayInWeek)){
                        return day == Integer.parseInt(dayInWeek.getDayInWeek());
                    }else{
                        return false;
                    }
                }else{
                    DateVo dayInWeek = tOperationdailyMapper.getDayInWeek(todayStr,"asc");
                    int day = Integer.parseInt(x.getPeriod().split("W")[1])%7;
                    if(Objects.nonNull(dayInWeek)){
                        return day == Integer.parseInt(dayInWeek.getDayInWeek());
                    }else{
                        return false;
                    }
                }
            }).collect(Collectors.toList());
            realSaveList.addAll(addList);
        }
        //按照M进行生成
        List<TOperationdaily> MList = collect.get("M");
        if(CollUtil.isNotEmpty(MList)){
            List<TOperationdaily> addList = MList.stream().filter(x -> {
                //如果带负号-则用7-对应的数字
                LocalDate parse = LocalDate.parse(todayStr, DateTimeFormatter.ofPattern("yyyyMMdd"));
                if(x.getPeriod().contains("-")){
                    DateVo dayInMonth = tOperationdailyMapper.getDayInMonth(todayStr,"desc");
                    //拿到对应的月度取余数
                    int day = Integer.parseInt(x.getPeriod().split("-")[1])%parse.now().lengthOfMonth();
                    //根据今天的字符串获取今天是这周的第几个工作日
                    if(Objects.nonNull(dayInMonth)){
                        return day == Integer.parseInt(dayInMonth.getWorkDayInMonth());
                    }else{
                        return false;
                    }
                }else{
                    DateVo dayInMonth = tOperationdailyMapper.getDayInMonth(todayStr,"asc");
                    int day = Integer.parseInt(x.getPeriod().split("M")[1])%parse.now().lengthOfMonth();
                    if(Objects.nonNull(dayInMonth)){
                        return day == Integer.parseInt(dayInMonth.getWorkDayInMonth());
                    }else{
                        return false;
                    }
                }
            }).collect(Collectors.toList());
            realSaveList.addAll(addList);
        }
        List<TOperationdaily> QList = collect.get("Q");
        if(CollUtil.isNotEmpty(QList)){
            List<TOperationdaily> addList = QList.stream().filter(x -> {
                LocalDate parse = LocalDate.parse(todayStr, DateTimeFormatter.ofPattern("yyyyMMdd"));
                int length = getQuarterLengthOfNow(parse);
                if(x.getPeriod().contains("-")){
                    DateVo dayInMonth = tOperationdailyMapper.getDayInQuarter(todayStr,"desc");
                    //拿到对应的数字对7取余数
                    int day = Integer.parseInt(x.getPeriod().split("-")[1])%length;
                    //根据今天的字符串获取今天是这周的第几个工作日
                    if(Objects.nonNull(dayInMonth)){
                        return day == Integer.parseInt(dayInMonth.getWorkDayInMonth());
                    }else{
                        return false;
                    }
                }else{
                    DateVo dayInQuarter = tOperationdailyMapper.getDayInQuarter(todayStr,"asc");
                    //获得季度多长
                    int day = Integer.parseInt(x.getPeriod().split("Q")[1])%length;
                    if(Objects.nonNull(dayInQuarter)){
                        return day == Integer.parseInt(dayInQuarter.getWorkDayInMonth());
                    }else{
                        return false;
                    }
                }
            }).collect(Collectors.toList());
            realSaveList.addAll(addList);
        }



        /**
         * 找到今日模板
         */
        QueryWrapper<TOperationdaily> sqw = new QueryWrapper<>();
        sqw.lambda().eq(TOperationdaily::getFlag,"1")
            .eq(TOperationdaily::getTemplatetype,bo.getTemplatetype())
            .eq(TOperationdaily::getSpecificdate,bo.getSpecificdate());
        List<TOperationdaily> specialOpList = tOperationdailyMapper.selectList(sqw);
        realSaveList.addAll(specialOpList);
        List<TOperationdailyResult> saveList = realSaveList.stream().map(x -> {
            TOperationdailyResult result = new TOperationdailyResult();
            result.setExcutedate(bo.getSpecificdate());
            result.setDailyid(x.getId());
            return result;
        }).collect(Collectors.toList());
        /**
         * 从总表过去今天已生成的数据
         */
        QueryWrapper<TOperationdailyResult> bqw = new QueryWrapper<>();
        bqw.lambda()
            .eq(TOperationdailyResult::getExcutedate,bo.getSpecificdate());

        List<String> existId = baseMapper.selectList(bqw)
            .stream()
            .map(x -> x.getDailyid())
            .collect(Collectors.toList());
        List<TOperationdailyResult> needSaveList = saveList.stream()
            .filter(x -> !existId.contains(x.getDailyid()))
            .collect(Collectors.toList());
        return baseMapper.insertBatch(needSaveList);
    }

    private int getQuarterLengthOfNow(LocalDate parse) {
        //判断是否闰年
        boolean leapYear = parse.isLeapYear();
        //获得当前是第几季度
        int i = parse.get(IsoFields.QUARTER_OF_YEAR);
        switch (i){
            case 1:
                return leapYear?91:90;
            case 2:
                return 91;
            case 3:
                return 92;
            case 4:
                return 92;
            default:
                return 0;
        }
    }

    @Override
    public R<String> finishWork(List<String> list) {
        List<TOperationdailyResult> collected = baseMapper.selectBatchIds(list)
            .stream()
            .filter(x->!"S".equals(x.getResult()))
            .map(x -> {
                x.setResult("S");
                x.setUpdateTime(new Date());
                x.setUpdateBy(LoginHelper.getUsername());
                return x;
            }).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collected)) {
             baseMapper.updateBatchById(collected);
        }
        return R.ok("操作成功");
    }

    @Override
    public int failWork(TOperationdailyResultBo bo) {
        bo.setId(bo.getId());
        bo.setResult(bo.getResult());
        bo.setMemo(bo.getMemo());
        TOperationdailyResult bean = BeanUtil.toBean(bo, TOperationdailyResult.class);
        return baseMapper.updateById(bean);
    }

    public static void main(String[] args) {
//        System.out.println(DateUtil.isLeapYear(LocalDate.now().getYear()));
//        System.out.println(DateUtil.isLeapYear(2024));
//        int dayOfQuarter = LocalDate.now().get(IsoFields.DAY_OF_QUARTER);
//        int quarterOfYear = LocalDate.now().get(IsoFields.QUARTER_OF_YEAR);
//        System.out.println(dayOfQuarter);
//        System.out.println(quarterOfYear);
//        String now = DateUtil.format(new Date(), "yyyyMMdd");
//        System.out.println(now);
//        System.out.println(LocalDate.parse(now, DateTimeFormatter.ofPattern("yyyyMMdd")));
    }
}
